package com.yunxin.admin.system.application.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunxin.admin.system.application.RoleApplicationService;
import com.yunxin.admin.system.application.assembler.RoleAssembler;
import com.yunxin.admin.system.application.command.AddRoleCommand;
import com.yunxin.admin.system.application.command.UpdateRoleCommand;
import com.yunxin.admin.system.domain.model.role.Role;
import com.yunxin.admin.system.domain.model.role.RoleMenuRepository;
import com.yunxin.admin.system.domain.model.role.RoleRepository;
import com.yunxin.admin.system.domain.model.user.UserRoleRepository;
import com.yunxin.core.admin.domain.AdminUser;
import com.yunxin.core.customer.domain.CustomerShipAllocation;
import com.yunxin.core.customer.service.CustomerShipAllocationService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 角色业务实现类
 *
 * @author zero°
 * @since 2023-05-22
 */
@Service
@RequiredArgsConstructor
public class RoleApplicationServiceImpl implements RoleApplicationService {

    private final RoleMenuRepository roleMenuRepository;

    private final UserRoleRepository userRoleRepository;

    private final RoleRepository roleRepository;

    private final RoleAssembler roleAssembler;

    @Autowired
    private CustomerShipAllocationService customerShipAllocationService;

    @Override
    public boolean saveRole(AddRoleCommand command) {
        Role role = roleAssembler.formAddRoleCommand(command);
        role.setBoke(1);
        role.setYd(1);
        return roleRepository.saveOrUpdate(role);
    }

    @Override
    public boolean updateRole(UpdateRoleCommand command) {
        Role role = roleAssembler.formUpdateRoleCommand(command);
        return roleRepository.saveOrUpdate(role);
    }


    @Override
    public boolean updateRoleStatus(Long roleId, Integer status) {
        return roleRepository.updateStatus(roleId, status);
    }

    @Override
    public boolean deleteRoles(String ids) {
        List<Long> roleIds = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();
        Optional.ofNullable(roleIds)
                .orElse(new ArrayList<>())
                .forEach(id -> {
                    long count = userRoleRepository.count(id);
                    Assert.isTrue(count <= 0, "该角色已分配用户，无法删除");
                    roleMenuRepository.remove(id);
                });
        return roleRepository.removeByIdList(roleIds);
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "system", key = "'routes'")
    public boolean updateRoleMenus(Long roleId, List<Long> menuIds) {
        // 删除角色菜单
        roleMenuRepository.remove(roleId);
        // 新增角色菜单
        if (CollUtil.isNotEmpty(menuIds)) {
            roleMenuRepository.saveBatch(roleId, menuIds);
        }
        return true;
    }

    @Override
    public List<AdminUser> userListByRoleCode(String code,Integer teamId) {
        return roleRepository.userListByRoleCode(code,teamId);
    }

    @Override
    public List<AdminUser> getUserList(String code, List<Integer> teamIds) {
        return roleRepository.getUserList(code,teamIds);
    }

    @Override
    public List<AdminUser> telephoneListBySalesmanId(String code, Integer salesmanId,Integer teamId) {
        LambdaQueryWrapper<CustomerShipAllocation> queryWrapper=new LambdaQueryWrapper();
        queryWrapper.eq(CustomerShipAllocation::getSalesmanId,salesmanId);
        List<CustomerShipAllocation> customerShipAllocations = customerShipAllocationService.list(queryWrapper);
        List<Integer> userIds = customerShipAllocations.stream().map(i -> i.getTelephoneId()).toList();
        if (ObjectUtils.isEmpty(userIds)){
            return null;
        }
        return roleRepository.telephoneListBySalesmanId(code,userIds,teamId);
    }


}
